package impl

import (
	"context"
	"time"

	"gitee.com/zatto/maudit/apps/audit"
	"gitee.com/zatto/maudit/common/logger"
	"gitee.com/zatto/maudit/common/validator"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
)

// 保存日志
func (i *impl) SaveAuditLog(ctx context.Context, in *audit.AuditLog) (*audit.AuditLog, error) {
	logger.L().Debug().Msgf("save log: %s", in)
	// 参数校验
	err := validator.V().Struct(in)
	if err != nil {
		return nil, err
	}

	// 存储
	_, err = i.getCol().InsertOne(ctx, in)
	if err != nil {
		return nil, err
	}
	return in, nil
}

// 查询日志
func (i *impl) QueryAuditLog(ctx context.Context, in *audit.QueryAuditLogRequest) (*audit.AuditLogSet, error) {
	// 构建容器
	set := audit.NewAuditLogSet()

	// 拼接搜索条件
	filter := bson.M{}

	if in.Request != "" {
		filter["request"] = bson.M{"$regex": in.Request, "$options": "im"}
	}

	if in.StartTime != 0 || in.EndTime != 0 {
		if in.EndTime == 0 {
			in.EndTime = time.Now().Unix()
		}
		filter["$and"] = bson.A{
			bson.D{{Key: "time", Value: bson.D{{Key: "$gte", Value: in.StartTime}}}},
			bson.D{{Key: "time", Value: bson.D{{Key: "$lte", Value: in.EndTime}}}},
		}
	}

	if in.Username != "" {
		filter["username"] = in.Username
	}

	if in.Operate != "" {
		filter["operate"] = in.Operate
	}

	opts := &options.FindOptions{}
	opts.SetLimit(int64(in.PageSize))
	opts.SetSkip(in.ComputeOffset())

	// 查询数据
	cursor, err := i.getCol().Find(ctx, filter, opts)
	if err != nil {
		return nil, err
	}

	for cursor.Next(ctx) {
		ins := audit.NewAuditLog()
		if err := cursor.Decode(ins); err != nil {
			return nil, err
		}
		// 注入容器
		set.Add(ins)
	}

	// 统计总数
	set.Total, err = i.col.CountDocuments(ctx, filter)
	if err != nil {
		return nil, err
	}

	// 返回结果
	return set, nil
}
